package net.wantong.tech.xa.service;

import lombok.extern.slf4j.Slf4j;
import net.wantong.tech.xa.dao.DeleteHisDataDao;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * 删除历史数据服务实现
 *
 * @author MaShibo
 * 日期 :  2019/9/4
 */
@Slf4j
@Service
public class DeleteHisDataService {


    @Resource
    private DeleteHisDataDao deleteHisDataDao;

    @Resource
    private ThreadPoolTaskExecutor executor;

    @Value("${exec.max.date}")
    private String maxDate;


    @Value("${delete.per.num}")
    private int deletePerNum;


    public void execute(LocalDate startDate, LocalDate endDate) {

        LocalDate maxLocalDate = LocalDate.parse(maxDate);
        if (endDate.compareTo(maxLocalDate) > 0) {
            log.warn("结束日期：{}，大于最大截止日期：{}，无法进行删除操作", endDate, maxLocalDate);
            return;
        }

        List<LocalDate> dateList = calculateAllDate(startDate, endDate);
        log.info("共需要删除{}天的消费流水数据：{}", dateList.size(), dateList);

        long start = System.currentTimeMillis();

        for (LocalDate deleteDate : dateList) {

            processSingle(deleteDate);

        }

        log.info("删除消费流水执行完成，耗时【{}】ms", System.currentTimeMillis() - start);
    }


    private void processSingle(LocalDate deleteLocalDate) {

        log.info("待删除日期：{}", deleteLocalDate);

        List<String> rowIds = deleteHisDataDao.querySelectedRowIds(deleteLocalDate.toDate(), deletePerNum);


        int rowIdCnt = rowIds.size();

        while (rowIdCnt > 0) {

            log.info("查询出{}条待删除的数据，开始删除操作", rowIdCnt);

            List<Future<Void>> futures = new ArrayList<Future<Void>>(rowIdCnt);
            for (String rowId : rowIds) {
                futures.add(executor.submit(new SingleDeleteHisDataCallable(rowId)));
            }

            for (Future<Void> future : futures) {
                try {
                    future.get();
                } catch (InterruptedException e) {
                    log.error(e.getMessage(), e);
                    Thread.currentThread().interrupt();
                } catch (ExecutionException e) {
                    log.error(e.getMessage(), e);
                }
            }

            log.info("{}条数据删除完成", rowIdCnt);

            rowIds = deleteHisDataDao.querySelectedRowIds(deleteLocalDate.toDate(), deletePerNum);
            rowIdCnt = rowIds.size();
        }


    }


    private void deleteHisDataByRowId(String rowId) {
        try {
            deleteHisDataDao.deleteTransOut(rowId);
            deleteHisDataDao.deleteTransOutExtend(rowId);
            deleteHisDataDao.deleteTransOutSplit(rowId);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }


    private List<LocalDate> calculateAllDate(LocalDate startDate, LocalDate endDate) {
        LocalDate temp;
        List<LocalDate> allDate = new ArrayList<LocalDate>();
        for (temp = startDate; temp.compareTo(endDate) <= 0; temp = temp.plusDays(1)) {
            allDate.add(temp);
        }
        return allDate;
    }


    public class SingleDeleteHisDataCallable implements Callable<Void> {

        private String rowId;

        SingleDeleteHisDataCallable(String rowId) {
            this.rowId = rowId;
        }

        @Override
        public Void call() {
            deleteHisDataByRowId(rowId);
            return null;
        }


    }


}
